// Copyright 2009 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Author: Jeff Stewart
// Code to locate a data file specifying trusted certifying authorities.

#include <QtCore/QDir>
#include <QtCore/QFile>
#include <QtCore/QString>
#include <QtCore/QTemporaryFile>

#include <cstdlib>

#include "probes/ssl.h"
#include "util/common.h"

namespace popdiag {

#ifdef _WIN32

// Import Internet Explorer CA certificates.

namespace {

// Qt Resources provide a cross platform way to embed data files in the
// binary.  BUT, some of our libraries (like openssl)
// doesn't use QFile to access them.
// So we need to create a local temporary file for this.
// Create one instance of this class for each such file as a static
// variable.  The temporary file is cleaned up in the destructor.
class LocalTempCopyOfResourceFile {
 public:
  explicit LocalTempCopyOfResourceFile(const QString &resource_path)
    : resource_path_(resource_path), temp_file_() {
    // Do not copy here (at static construction time), as resource
    // bundle is not initialized.
  }

  ~LocalTempCopyOfResourceFile() {
  }

  bool GetLocalTempPath(QString *out) {
    if (temp_file_ != NULL) {
      *out = temp_file_->fileName();
      return true;
    }

    if (!QFile::exists(resource_path_)) {
      return false;
    }

    // File was embedded in the executable. Write out a temporary copy.
    temp_file_.reset(QTemporaryFile::createLocalFile(resource_path_));
    *out = temp_file_->fileName();
    return true;
  }

 private:
  QString resource_path_;
  scoped_ptr<QTemporaryFile> temp_file_;
};

}  // anonymous namespace

bool GetCACertFilePath(QString *out) {
  // Leading colon means we're loading from the resource bundle.
  static LocalTempCopyOfResourceFile ca_file(":/certs/etc/castrustedbyie.pem");

  if (ca_file.GetLocalTempPath(out)) {
    return true;
  }

  // look in current working directory:
  QDir here = QDir::currentPath();
  QString path = here.filePath("etc/castrustedbyie.pem");
  if (QFile::exists(path)) {
    *out = path;
    return true;
  }

  return false;
}

bool SetCACertificates(QSslSocket *socket) {
  QString path;
  if (GetCACertFilePath(&path)) {
    socket->setCaCertificates(QSslCertificate::fromPath(path));
    return true;
  }
  return false;
}

#else  // !_WIN32

// No point in importing Internet Explorer CA certificates.
bool SetCACertificates(QSslSocket * /*socket*/) {
  return true;
}

#endif  // !_WIN32

}  // namespace popdiag
